package com.dong.multithreading;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

/**
 * 环栅栏
 * 字面意思回环栅栏，通过它可以实现让一组线程等待至某个状态之后再全部同时执行。叫做回环是因为当所有等待线程都被释放以后，CyclicBarrier可以被重用。
 * 我们暂且把这个状态就叫做barrier，当调用await()方法之后，线程就处于barrier了。
 * CyclicBarrier类位于java.util.concurrent包下，CyclicBarrier提供2个构造器：
 * 1、public CyclicBarrier(int parties, Runnable barrierAction) { }
 * 2、public CyclicBarrier(int parties) { }
 *
 * 参数parties指让多少个线程或者任务等待至barrier状态；参数barrierAction为当这些线程都达到barrier状态时会执行的内容。
 * 然后CyclicBarrier中最重要的方法就是await方法，它有2个重载版本：
 * 1、public int await() throwsInterruptedException, BrokenBarrierException { };
 * 2、public int await(longtimeout, TimeUnit unit)throwsInterruptedException,BrokenBarrierException,TimeoutException { };
 */
public class CyclicBarrierTest {

    public static void main(String[] args) {
        int n = 4;
        CyclicBarrier barrier = new CyclicBarrier(n, new Print());
        for (int i = 0; i < n; i++) {
            new Writer(barrier).start();
        }
        // 从结果可以看出，当四个线程都到达barrier状态后，会从四个线程中选择一个线程去执行Runnable。
    }

    static class Writer extends Thread {
        private CyclicBarrier cyclicBarrier;

        Writer(CyclicBarrier cyclicBarrier) {
            this.cyclicBarrier = cyclicBarrier;
        }

        @Override
        public void run() {
            System.out.println("线程" + Thread.currentThread().getName() + "正在写入数据...");
            try {
                Thread.sleep(5000);// 以睡眠来模拟写入数据操作
                System.out.println("线程" + Thread.currentThread().getName() + "写入数据完毕，等待其他线程写入完毕");
                cyclicBarrier.await();
                System.out.println("线程" + Thread.currentThread().getName() + "End");
            } catch (BrokenBarrierException | InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    static class Print extends Thread {
        @Override
        public void run() {
            System.out.println("线程" + Thread.currentThread().getName() + "所有线程写入完毕，继续处理其他任务...");
        }

    }
}
